起床時間:0700
本來想刷別的,可是昨天另外兩個解還沒寫完
Given an array of integers nums and an integer target, return the indices i and j such that nums[i] + nums[j] == target and i != j.
You may assume that every input has exactly one pair of indices i and j that satisfy the condition.
Return the answer with the smaller index first.
暴力解兩層 for 迴圈搞定!
class Solution:
def twoSum(self, nums: List[int], target: int) -> List[int]:
pairs = []
for i in range(len(nums)):
pairs.append((nums[i], i))
pairs.sort()
i = 0
j = len(nums) - 1
while i < j:
tmp_sum = pairs[i][0] + pairs[j][0]
if target == tmp_sum:
return [min(pairs[i][1], pairs[j][1]), max(pairs[i][1], pairs[j][1])]
if target > tmp_sum:
i += 1
else:
j -= 1
return []
原本有想到排序,從頭跟尾開始找,但是忘記記index,最後就算找了數也傳不回去。
加上id以後變成有點難想。
思考應該是這樣才對:
假設例子:
nums = [4, 1, 5, 3]
target = 6
Step 1. 建立 pairs
pairs = [(4,0), (1,1), (5,2), (3,3)]
Step 2. 排序
pairs.sort()
排序後:
i (索引) pairs[i] pairs[i][0] (值 value) pairs[i][1] (原索引 index)
0 (1, 1) 1 1
1 (3, 3) 3 3
2 (4, 0) 4 0
3 (5, 2) 5 2
Step 3. 雙指標 (two pointers)
初始情況:
left = 0 → 指到 (1,1)
pairs[left][0] = 1
pairs[left][1] = 1
right = 3 → 指到 (5,2)
pairs[right][0] = 5
pairs[right][1] = 2
計算:
s = pairs[left][0] + pairs[right][0]
(s = 1 + 5 = 6)
回傳:
[i1, i2] = [pairs[left][1], pairs[right][1]]
(= [1, 2] ← 原始索引)
總結圖(簡化版)
i pairs[i] pairs[i]0 pairs[i]1
0 (1, 1) 1 1
1 (3, 3) 3 3
2 (4, 0) 4 0
3 (5, 2) 5 2
return [min(pairs[i][1], pairs[j][1]), max(pairs[i][1], pairs[j][1])]
min & max沒寫的話會出事。
排序必須指定 key=lambda p: p[1](按第 2 欄=值)
pairs = [(i, nums[i]) for i in range(len(nums))] # (idx, val)
pairs.sort(key=lambda p: p[1])
在 Python 裡,lambda = 臨時小函式(anonymous function, 匿名函數)
pairs = [(val, idx) for idx, val in enumerate(nums)]
等同
pairs = []
for i in range(len(nums)):
pairs.append((nums[i], i))